package com.tsc.common.response;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;

/**
 * Created with IntelliJ IDEA.
 *
 * @Author: chentl
 * @Date: 2025/08/15/22:43
 * @Description: 全局响应处理器
 */
@RestControllerAdvice
public class GlobalResponseHandler implements ResponseBodyAdvice<Object> {
    @Autowired
    private ObjectMapper objectMapper;

    @Value("${spring.application.name:unknown}")
    private String applicationName;

    // 支持所有返回类型，除了ApiResponse本身和特定注解标记的
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> converterType) {
        return !returnType.getParameterType().isAssignableFrom(ApiResponse.class)
                && !returnType.hasMethodAnnotation(NoWrapResponse.class);
    }

    // 在返回前处理响应体
    @Override
    public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType,
                                  Class<? extends HttpMessageConverter<?>> selectedConverterType,
                                  ServerHttpRequest request, ServerHttpResponse response) {

        // 处理字符串类型（需要特殊处理）
        if (body instanceof String) {
            try {
                response.getHeaders().setContentType(MediaType.APPLICATION_JSON);
                return objectMapper.writeValueAsString(ApiResponse.success(body)
                        .withPath(request.getURI().getPath())
                        .withTraceId(MDC.get("traceId")));
            } catch (JsonProcessingException e) {
                throw new RuntimeException("JSON序列化失败", e);
            }
        }

        // 处理void返回类型
        if (returnType.getParameterType().equals(void.class)) {
            return ApiResponse.success()
                    .withPath(request.getURI().getPath())
                    .withTraceId(MDC.get("traceId"));
        }

        // 常规类型处理
        if (body == null && Void.class.equals(returnType.getParameterType())) {
            return ApiResponse.success()
                    .withPath(request.getURI().getPath())
                    .withTraceId(MDC.get("traceId"));
        }

        // 已有数据的情况
        return ApiResponse.success(body)
                .withPath(request.getURI().getPath())
                .withTraceId(MDC.get("traceId"));
    }
}
